package com.xbongbong.crm.help;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.utils.HttpHelper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.util.FineClueUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.model.FineClueCompanyModel;
import com.xbongbong.paas.model.FineClueConsumptionModel;
import com.xbongbong.paas.model.FineClueUserModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.FineClueUrlConstant;
import com.xbongbong.pro.domain.entity.FineClueCompanyEntity;
import com.xbongbong.pro.domain.entity.FineClueUserEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.FineClueEnum;
import com.xbongbong.pro.enums.menu.enums.FineClueStatusEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CompetitorEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.FineCluePageRouteEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author mingliang
 * @Description 精线索帮助类
 * @Date 2021/10/29 10:47
 **/
@Component
public class FineClueHelp {

    private static final Logger LOG = LoggerFactory.getLogger(FineClueHelp.class);
    private static final String FINE_CLUE_COMPANY_SIGN = "fineClueCompanySign";
    private static final String CONTENT = "content";
    private static final String PUSHURL = "pushUrl";
    private static final String XBBDOSAGEURL = "xbbDosageUrl";
    private static final String XBBDOSAGEPUSHURL = "xbbDosagePushUrl";

    @Resource
    public PaasRedisHelper paasRedisHelper;
    @Resource
    public ProBaseConfig proBaseConfig;
    @Resource
    private FineClueConsumptionModel fineClueConsumptionModel;
    @Resource
    private FineClueCompanyModel fineClueCompanyModel;
    @Resource
    private FineClueUserModel fineClueUserModel;
    
//    此类的getSign方法和getRouteData方法本地调试时，需要将pushUrl，xbbDosageUrl地址修改成本机服务地址，支持外网访问
//    String pushUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.PUSH_URL;
//    String xbbDosageUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.XBB_DOSAGE_URL;
//    String xbbDosagePushUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.XBB_DOSAGEPUSH_URL;
//    String pushUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.MOBILE_PUSH_URL;
//    String xbbDosageUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.MOBILE_XBB_DOSAGE_URL;
//    String xbbDosagePushUrl = "http://xbb12345678.vaiwan.com/" + FineClueUrlConstant.MOBILE_XBB_DOSAGEPUSH_URL;
    String pushUrl = "";
    String xbbDosageUrl = "";
    String xbbDosagePushUrl = "";

    public String getSign(String corpid, String userid, String password ,String platform) {
        String value = paasRedisHelper.getValue(FINE_CLUE_COMPANY_SIGN, corpid);
        if (StringUtil.isNotEmpty(value)) {
            return value;
        }
        String securityUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.SECURITY_URL;
        // 回调地址：转客户/销售线索，查看用量
        if (Objects.equals(platform,PlatFormEnum.DINGTALK.getValue())){
            pushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_PUSH_URL;
            xbbDosageUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_XBB_DOSAGE_URL;
            xbbDosagePushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_XBB_DOSAGEPUSH_URL;
//            pushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_PUSH_URL;
//            xbbDosageUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_XBB_DOSAGE_URL;
//            xbbDosagePushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_XBB_DOSAGEPUSH_URL;
        }else {
            pushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.PUSH_URL;
            xbbDosageUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.XBB_DOSAGE_URL;
            xbbDosagePushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.XBB_DOSAGEPUSH_URL;
//            pushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.PUSH_URL;
//            xbbDosageUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.XBB_DOSAGE_URL;
//            xbbDosagePushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.XBB_DOSAGEPUSH_URL;
        }
        String base64PushUrl = Base64.encodeBase64String(pushUrl.getBytes());
        String base64XbbDosageUrl = Base64.encodeBase64String(xbbDosageUrl.getBytes());
        String base64xbbDosagePushUrl = Base64.encodeBase64String(xbbDosagePushUrl.getBytes());

        JSONObject request = new JSONObject();
        String s = userid + ":" + password + ":" + "companyNameSearch";
        String content = FineClueUtil.AESUrlSafeEncrypt(s, proBaseConfig.getFineClueKey(), "ECB");
//        request.put("company", corpid);
        request.put(CONTENT, content);
        request.put(PUSHURL, base64PushUrl);
        request.put(XBBDOSAGEURL, base64XbbDosageUrl);
        request.put(XBBDOSAGEPUSHURL, base64xbbDosagePushUrl);
        JSONObject jsonObject = null;

        //鉴权时区分web端，移动端
        Map<String, String> headers = new HashMap<>();
        if (Objects.equals(platform,PlatFormEnum.DINGTALK.getValue())){
            headers.put("xbbFromType","app");
        }else {
            headers.put("xbbFromType","web");
        }
        // 兼容推送新老逻辑
        headers.put("isNew","true");
        try {
            jsonObject = HttpHelper.httpPostDingtalk(securityUrl, request ,headers);
        } catch (OApiException e) {
            LOG.error("精线索鉴权失败：request：{} data{}", request, jsonObject);
        }
        if (jsonObject == null || jsonObject.getInteger("errcode").intValue() != 200) {
            LOG.error("精线索鉴权失败：request：{}data{}", request, jsonObject);
            return null;
        }
        String sign = jsonObject.getJSONObject("data").getString("sign");
        paasRedisHelper.setValue(FINE_CLUE_COMPANY_SIGN, corpid, sign, TimeConstant.SEARCH_EFFECTIVE_TIME);
        return sign;
    }

    public JSONObject getRouteData(String dataId, String userid, String password, FineCluePageRouteEnum pageRouteEnum, Boolean isIndustSearch, String platform) {
        String securityUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.SECURITY_URL;
        JSONObject request = new JSONObject();
        String s = userid + ":" + password + ":" + pageRouteEnum.getRoute();
        String content = FineClueUtil.AESUrlSafeEncrypt(s, proBaseConfig.getFineClueKey(), "ECB");
        if (pageRouteEnum == FineCluePageRouteEnum.DETAIL){
            request.put("company", dataId);
            request.put("isIndustSearch",isIndustSearch);
        }
        request.put(CONTENT, content);
        // 回调地址：转客户/销售线索，查看用量
        if (Objects.equals(platform,PlatFormEnum.DINGTALK.getValue())){
            pushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_PUSH_URL;
            xbbDosageUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_XBB_DOSAGE_URL;
            xbbDosagePushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.MOBILE_XBB_DOSAGEPUSH_URL;
//            pushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_PUSH_URL;
//            xbbDosageUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_XBB_DOSAGE_URL;
//            xbbDosagePushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.MOBILE_XBB_DOSAGEPUSH_URL;
        }else {
            pushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.PUSH_URL;
            xbbDosageUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.XBB_DOSAGE_URL;
            xbbDosagePushUrl = proBaseConfig.getProjectDingtalkUrl() + FineClueUrlConstant.XBB_DOSAGEPUSH_URL;
//            pushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.PUSH_URL;
//            xbbDosageUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.XBB_DOSAGE_URL;
//            xbbDosagePushUrl = "http://bbpk6h.natappfree.cc/" + FineClueUrlConstant.XBB_DOSAGEPUSH_URL;
        }
        String base64PushUrl = Base64.encodeBase64String(pushUrl.getBytes());
        String base64XbbDosageUrl = Base64.encodeBase64String(xbbDosageUrl.getBytes());
        String base64xbbDosagePushUrl = Base64.encodeBase64String(xbbDosagePushUrl.getBytes());
        request.put(PUSHURL, base64PushUrl);
        request.put(XBBDOSAGEURL, base64XbbDosageUrl);
        request.put(XBBDOSAGEPUSHURL,base64xbbDosagePushUrl);
        JSONObject jsonObject = null;
        //鉴权时区分web端，移动端
        Map<String, String> headers = new HashMap<>();
        if (Objects.equals(platform, PlatFormEnum.DINGTALK.getValue())){
            headers.put("xbbFromType","app");
        }else {
            headers.put("xbbFromType","web");
        }
        // 兼容推送新老逻辑
        headers.put("isNew","true");
        try {
            jsonObject = HttpHelper.httpPostDingtalk(securityUrl, request, headers);
        } catch (OApiException e) {
            LOG.error("精线索鉴权失败：fineUrl：{}data{}", securityUrl, request);
            e.printStackTrace();
        }
        if (jsonObject == null || 200 != jsonObject.getInteger("errcode")) {
            LOG.error("精线索鉴权失败：fineUrl：{}data{}", securityUrl, request);
        }
        if (Objects.isNull(jsonObject) || !jsonObject.containsKey(StringConstant.JSON_DATA)) {
            LOG.error("获取精线索数据失败：data{}", jsonObject);
            return null;
        }

        JSONObject data = jsonObject.getJSONObject(StringConstant.JSON_DATA);
        String sign = data.getString("sign");
        String url = data.getString("url");
        data.put("url",url+"?sign="+sign);
        return data;
    }

    /***
     * @description: 工商查询数据回显
     * @param: pid
     * @param: sign
     * @return: com.alibaba.fastjson.JSONObject
     * @author: zhushuainan
     * @date: 2022/1/20 19:24
     */
    public JSONObject dataBackfill(String pid,String sign){
        String baseInfoUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.BASE_INFO_ENTERPRISE_URL + "/" + pid + "?sign=" + sign;
        // 发送get请求调用企业基本信息
        JSONObject baseInfo = null;
        try {
            baseInfo = HttpHelper.httpGetFineClue(baseInfoUrl);
        } catch (OApiException e) {
            LOG.error("精线索查询详情失败：fineUrl：{}", baseInfoUrl);
        }

        return baseInfo;
    }
    /*** 
     * @description: 从三方获取套餐用量 用总量&&已使用的量
     * @param: sign 
     * @return: com.alibaba.fastjson.JSONObject 
     * @author: zhushuainan
     * @date: 2022/1/21 15:49
     */
    public JSONObject getMealConsumption(String sign){
        String baseInfoUrl = proBaseConfig.getFineClueUrl()+FineClueUrlConstant.FINECLUECONSUMPTION_URL+"?sign="+sign;
        // 发送get请求查询精线索套餐用量
        JSONObject baseInfo = null;
        try {
            baseInfo= HttpHelper.httpGetFineClue(baseInfoUrl);
        } catch (OApiException e) {
            LOG.error("精线索套餐用量查询失败：fineUrl：{}", baseInfoUrl);
            LOG.error("精线索套餐用量查询错误",e);
        }
        return baseInfo;
    }
    /*** 
     * @description: 模糊查企业
     * @param: sign
     * @param: keyword
     * @return: com.alibaba.fastjson.JSONObject 
     * @author: zhushuainan
     * @date: 2022/1/21 15:59
     */
    public JSONObject fuzzySearchEnterprise(String sign, String keyword){
        String baseInfoUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.LIST_ENTERPRISE_URL + "/" + keyword + "?sign=" + sign;
        // 发送get请求调用企业基本信息
        JSONObject baseInfo = null;
        try {
            baseInfo = HttpHelper.httpGetFineClue(baseInfoUrl);
        } catch (OApiException e) {
            LOG.error("精线索分页查询失败：fineUrl：{}", baseInfoUrl);
        }
        
        return baseInfo;
    }

    /**
     * 搜客数据推送回调
      * @param jsonObject
     * @param sign
     * @return
     */
    public JSONObject dataPushCallBack(JSONObject jsonObject, String sign){
        String baseInfoUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.DATA_PUSH_CALLBACK_URL + "?sign=" + sign;
        JSONObject baseInfo = null;
        try {
            baseInfo = HttpHelper.httpPostDingtalk(baseInfoUrl, jsonObject);
        } catch (OApiException e) {
            LOG.error("souke dataPushCallBack is error e:{},baseInfo:{}", e, baseInfo);
        }
        return baseInfo;
    }
    /**
     * 精线索是否可用
     * 搜客 || 工商查询　有一个可用即为可用
     *
     * @param corpid 公司id
     * @param fineClueEnum 精线索套餐类型
     * @return boolean
     */
    public boolean fineClueUsable(String corpid, FineClueEnum fineClueEnum) {
        FineClueCompanyEntity businessEntity = fineClueCompanyModel.getByCorpid(corpid, fineClueEnum.getType());
        return businessEntity != null && businessEntity.getExtraExpiry() > DateUtil.getInt();
    }

    /**
     * 通过公司名返回精线索的数据id
     *
     * @param corpid 公司id
     * @param companyName 公司名称
     * @return pid
     */
    public String getPidByCompanyName(String corpid, String companyName , String platform) {
        // 名称为空不查询
        if (StringUtil.isEmpty(companyName)) {
            return null;
        }
        FineClueUserEntity clueUserEntity = fineClueUserModel.getSingleUserByCorpid(corpid);
        //如果无账户
        if (Objects.isNull(clueUserEntity)) {
            return null;
        }

        boolean flag = false;
        FineClueCompanyEntity businessEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.BUSINESS.getType());
        FineClueCompanyEntity soukeEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.FINE_CLUE.getType());
        // TODO 如果精线索不再提供工商查询功能，这部分逻辑需要去掉
        if (businessEntity != null && businessEntity.getExtraExpiry() > DateUtil.getInt()) {
            flag = true;
        }
        if (soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
            flag = true;
        }

        if (!flag) {
            return null;
        }

        try {
            companyName = URLEncoder.encode(companyName, "utf-8");
        } catch (UnsupportedEncodingException e) {
            companyName = null;
        }
        if (Objects.isNull(companyName)) {
            return null;
        }

        String sign = getSign(clueUserEntity.getRegisterCorpid(), clueUserEntity.getClueUserId(), clueUserEntity.getClueUserPassword() ,platform);
        if (Objects.isNull(sign)) {
            return null;
        }
        String baseInfoUrl = proBaseConfig.getFineClueUrl() + FineClueUrlConstant.LIST_ENTERPRISE_URL + "/" + companyName + "?sign=" + sign;
        // 发送get请求调用企业基本信息
        JSONObject baseInfo = null;
        try {
            baseInfo = HttpHelper.httpGetFineClue(baseInfoUrl);
        } catch (OApiException e) {
            LOG.error("精线索分页查询失败：fineUrl：{}", baseInfoUrl);
        }
        if (Objects.isNull(baseInfo) || !baseInfo.containsKey(StringConstant.JSON_DATA)) {
            return null;
        }
        JSONArray jsonArray = baseInfo.getJSONArray(StringConstant.JSON_DATA);
        if (CollectionsUtil.isEmpty(jsonArray)) {
            return null;
        }
        try {
            for (Object object : jsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                String entName = URLEncoder.encode(jsonObject.getString("entName"), "utf-8");
                if (Objects.equals(companyName,entName)) {
                    return jsonObject.getString("pid");
                }
            }
        } catch (UnsupportedEncodingException e) {
            LOG.warn("精线索数据encode失败", e);
        }
        return  null;
    }

    /***
     * 获取精线索使用量
     *
     * @param corpid　公司id
     * @param: userId 员工id
     * @param: clueUseType 精线索上限使用类型，1：每天；2：每月
     * @throws
     * @return java.lang.Integer
     * @author hongxiao
     * @date 2021-12-29 12:01
     * @since
     * @version
     */
    public Integer getUseNumber(String corpid, String userId, Integer clueUseType) {
        long startTime = Objects.equals(BasicConstant.ONE, clueUseType) ? DateTimeUtil.getTodayInt() : DateTimeUtil.getFirstDateOfThisMonth();
        long endTime = DateTimeUtil.getInt();

        List<Integer> statusIn = new ArrayList<>();
        statusIn.add(FineClueStatusEnum.UNLOCK.getCode());
        statusIn.add(FineClueStatusEnum.RELEASE.getCode());
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("statusIn", statusIn);
        param.put("startUseTime", startTime);
        param.put("endUseTime", endTime);
        if (Objects.nonNull(userId)) {
            param.put("userId", userId);
        }

        return fineClueConsumptionModel.getEntitysCount(param);
    }

    /***
     * 有工商查询或搜索功能的公司业务
     *
     * @param corpid
     * @param businessType
     * @param distributorMark
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-10 17:05
     * @since
     * @version
     */
    public boolean isFineClueByCorpid(String corpid, Integer businessType, Integer distributorMark) {
        return (Objects.isNull(distributorMark) || Objects.equals(distributorMark, DistributorMarkEnum.OTHER.getCode()))
                && hasBusinessSearch(businessType)
                && (fineClueUsable(corpid, FineClueEnum.BUSINESS) || fineClueUsable(corpid, FineClueEnum.FINE_CLUE));
    }

    /***
     * 有工商查询或搜索功能的公司业务
     *
     * @param corpid
     * @param businessType
     * @param distributorMark
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-14 11:18
     * @since
     * @version
     */
    public boolean isBusinessSearch(String corpid, Integer businessType, Integer distributorMark) {
        return (Objects.isNull(distributorMark) || Objects.equals(distributorMark, DistributorMarkEnum.OTHER.getCode()))
                && hasBusinessSearch(businessType) && fineClueUsable(corpid, FineClueEnum.BUSINESS);
    }

    /***
     * 支持工商查询的业务类型
     * 客户、销售线索、竞争对手、供应商
     *
     * @param
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-10 11:20
     * @since
     * @version
     */
    public boolean hasBusinessSearch(Integer businessType) {
        return Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode(),
                XbbRefTypeEnum.COMPETITOR.getCode(),XbbRefTypeEnum.SUPPLIER.getCode()).contains(businessType);
    }

    /***
     * 支持搜索的业务类型
     * 客户、销售线索
     *
     * @param
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-10 11:21
     * @since
     * @version
     */
    public boolean hasFineClue(Integer businessType) {
        return Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode()).contains(businessType);
    }

    /***
     * 工商查询主字段类型（公司名称）
     *
     * @param attr
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-10 17:07
     * @since
     * @version
     */
    public boolean isMainAttr(String attr) {
        return Arrays.asList(CustomerManagementEnum.NAME.getAttr(), ClueEnum.COMPANY_NAME.getAttr(), CompetitorEnum.NAME.getAttr(), SupplierEnum.SUPPLIER_NAME.getAttr()).contains(attr);
    }

    /***
     * 工商查询地址字段类型
     *
     * @param attr
     * @throws
     * @return boolean
     * @author hongxiao
     * @date 2023-02-10 17:08
     * @since
     * @version
     */
    public boolean isAddressAttr(String attr) {
        return Arrays.asList(CustomerManagementEnum.ADDRESS.getAttr(), ClueEnum.ADDRESS.getAttr(), CompetitorEnum.ADDRESS.getAttr(), SupplierEnum.ADDRESS.getAttr()).contains(attr);
    }
}
